local require = require
local ngx = ngx
local string = string
local math = math
local tonumber = tonumber
local next = next

local uu = require("modules.commhm.utils")
local log = require("modules.commhm.log")
local config = require("modules.business_common.business_config")
local utils  = require("modules.business_common.business_utils")


local FOO = {
    _VERSION = '0.0.1',
    TYPE = {
        WHITE_IP = 1, -- IP白名单
        IP_RANGE = 2  -- IP段白名单
    }
}

local calculate_ip_number = function(ip)
    local ip_decimal = 0
    local postion = 2  --只检测ip的前三个字段"127.0.0.*"
    for v in string.gmatch(ip, [[%d+]]) do
        if postion < 0 then
            break
        end
        ip_decimal = ip_decimal + math.pow(255, postion) * v
        postion = postion - 1
    end
    return ip_decimal
end

-- IP白名单检查
--@param t_white_ip = {"127.0.0.1" = FOO.TYPE.WHITE_IP "127.0.0.*" = FOO.TYPE.IP_RANGE}

local check_white_ip = function(t_white_ip)
    if not t_white_ip  then -- 无配置.默认挡掉
        return false,"配置传参为nil"
    end
    if uu.tableIsEmpty(t_white_ip or {}) then  --配置为空,默认挡掉
        return false,"配置传参为空"
    end
    --全局通过
    if t_white_ip['all'] and t_white_ip['all'] == 1 then return true end

    --IP判定
    local real_client_ip = utils.real_client_ip() or "nil"
    if real_client_ip == nil then
        return false,"取不到请求源地址(客户端地址)"
    end

    if t_white_ip[real_client_ip] and t_white_ip[real_client_ip] == FOO.TYPE.WHITE_IP then return true end

    --IP段判定
    local ip_list = {}
    for ip,v in next,t_white_ip do
        if tonumber(v) == FOO.TYPE.IP_RANGE then 
            local ip_decimal = calculate_ip_number(ip)
            ip_list[ip_decimal] = true
        end
    end
    local real_client_ip_decimal = calculate_ip_number(real_client_ip)
    if uu.tableNotEmpty(ip_list) and ip_list[real_client_ip_decimal] then        
        return true
    end

    return false, "无配置"
end

-- 默认的白名单检查
FOO.check = function(t_white_ip)
    --环境检测
    if config.debug_env() then 
        return true
    end
    --白名单检查
    local ret,msg = check_white_ip(t_white_ip);
    if not ret then
        log.day_list("check_white_ip",(ngx.ctx.xff or ngx.var.remote_addr or "nil"),ngx.ctx.m_params.uin,ngx.var.request_uri,(msg or "nil"),uu.to_str(t_white_ip or "nil"))
        return false
    end
    return true
end

return FOO
